#include "BulletContainer.h"




bool BulletContainer::_checkToKillBullet(BulletEntity* bullet)
{
	if (!bullet->checkAlive()) {
		_data->bullets->erase(bullet->getAbstractData()->getId());
		GameDeviceSingleton::getInstance()->getGameBullet()->deleteBullet(bullet, _data->bulletArmy);
		delete bullet;
		_data->currentBulletFired--;
		return false;
	}

	return true;
}

void BulletContainer::setMaxBullet(int max)
{
	this->_data->maxBulletAtTheSame = max;
}

BulletContainer::BulletContainer(Rect* actorRect, BulletArmies bulletArmy)
{
	_data = new BulletContainerData(actorRect, bulletArmy);
}

void BulletContainer::updateData(int distanceForLive, int delayOfTwoBullet, int maxBulletAtTheSame, int bulletType)
{
	_data->updateData(distanceForLive, delayOfTwoBullet, maxBulletAtTheSame, bulletType);
}

bool BulletContainer::checkCanFire()
{
	// if current bullet equals max bullet can fire and delaytime, return false
	bool passDelay = _data->currentFireCounterTime <= 0;
	bool passMaxFire = _data->currentBulletFired < _data->maxBulletAtTheSame;

	bool result = passMaxFire && passDelay;

	if (result) {
		_data->currentFireCounterTime = 0;
	}

	return result;
}

bool BulletContainer::fire(double x, double y, int direction, Rect* targetRect, BulletBehavior* behavior)
{
	// Create bullet to fire with current bullet type
	BulletEntity* bullet = BulletFactory::createBullet(_data->bulletArmy, _data->bulletType, x, y, direction, _data->actorRect, targetRect, false, _data->distanceForLive);
	bullet->setBulletBehavior(behavior);
	behavior->setBulletData(bullet->getBulletData());
	bullet->fire();
	// Put bullet to hash map
	_data->bullets->insert(std::make_pair(bullet->getAbstractData()->getId(), bullet));
	GameDeviceSingleton::getInstance()->getGameBullet()->addBullet(_data->bulletArmy, bullet);
	// Update container data to manage current contaier state
	_data->currentBulletFired++;
	_data->currentFireCounterTime = _data->delayOfTwoBullets;

	return _checkToKillBullet(bullet);
}

BulletEntity* BulletContainer::fire(double x, double y, int direction, Rect* targetRect)
{
	return fire(x, y, direction, targetRect, false);
}

BulletEntity* BulletContainer::fire(double x, double y, int direction, Rect* targetRect, bool isHalf)
{
	// Create bullet to fire with current bullet type
	BulletEntity* bullet = BulletFactory::createBullet(_data->bulletArmy, _data->bulletType, x, y, direction, _data->actorRect, targetRect, isHalf, _data->distanceForLive);
	bullet->fire();
	// Put bullet to hash map
	_data->bullets->insert(std::make_pair(bullet->getAbstractData()->getId(), bullet));
	GameDeviceSingleton::getInstance()->getGameBullet()->addBullet(_data->bulletArmy, bullet);
	// Update container data to manage current contaier state
	_data->currentBulletFired++;
	_data->currentFireCounterTime = _data->delayOfTwoBullets;

	return bullet;
}

int BulletContainer::getCurrentBulletType()
{
	return _data->bulletType;
}

void BulletContainer::draw(long time)
{
	// loop in all bullets to draw 
	/*HM_BULLET::iterator it = _data->bullets->begin();
	for (; it != _data->bullets->end(); it++) {
	it->second->draw(time);
	}*/
}

void BulletContainer::update(long time)
{
	if (_data->currentFireCounterTime > 0) {
		_data->currentFireCounterTime--;
	}
	// loop int all bullets to update
	BulletEntity* bullet;
	HM_BULLET::iterator itnext = _data->bullets->begin();
	HM_BULLET::iterator it = _data->bullets->begin();
	if (itnext != _data->bullets->end()) itnext++;
	while (it != _data->bullets->end()) {
		//it->second->update(time);
		// Check bullet with distance for live, if greater than, will be killed
		bullet = it->second;
		_checkToKillBullet(bullet);
		it = itnext;
		if (itnext != _data->bullets->end())itnext++;
	}
}
